using System;
using System.Diagnostics;
using System.DirectoryServices;
using System.Security.Principal;
using SG.Productivity.DesktopControlPanel.Properties;

namespace SG.Productivity.DesktopControlPanel.Support
{
    internal class UserInfo
    {
        private const string SamAccountNameProperty = "SAMAccountName";
        private const string GivenNameProperty = "givenName";
        private const string SurnameProperty = "sn";
        private const string TelephoneNumberProperty = "telephoneNumber";

        private static WindowsIdentity _currentWindowsUser;
        private static UserInfo _currentUserInfo;

        private readonly string _surname;
        private readonly string _givenName;
        private readonly string _accountName;
        private readonly string _telephoneNumber;

        private UserInfo(string name)
        {
            var searcher = new DirectorySearcher(new DirectoryEntry(Resources.UserInfo_LDAP_UserRoot))
            {
                Filter = string.Format("({0}={1})", SamAccountNameProperty, name)
            };
            searcher.PropertiesToLoad.AddRange(new[] { SamAccountNameProperty, GivenNameProperty, SurnameProperty, TelephoneNumberProperty });
            var entry = searcher.FindOne();

            if (entry != null)
            {
                _accountName = entry.Properties[SamAccountNameProperty][0].ToString();
                _givenName = entry.Properties[GivenNameProperty][0].ToString();
                _surname = entry.Properties[SurnameProperty][0].ToString();
                _telephoneNumber = entry.Properties[TelephoneNumberProperty][0].ToString();
            }
        }

        public string Surname { get { return _surname; } }

        public string GivenName { get { return _givenName; } }

        public string AccountName { get { return _accountName; } }

        public string TelephoneNumber { get { return _telephoneNumber; } }

        public static bool TryGetCurrentUser(out WindowsIdentity user, out UserInfo info)
        {
            user = _currentWindowsUser ?? (_currentWindowsUser = WindowsIdentity.GetCurrent());
            var hasUser = user != null;

            info = hasUser && _currentUserInfo != null
                       ? _currentUserInfo
                       : (_currentUserInfo = new UserInfo(user.GetName()));
            return hasUser && info != null;
        }

    }

    internal static class IIDentityEx
    {

        public static string GetName(this IIdentity user)
        {
            int domainSep;
            return (domainSep = user.Name.IndexOf('\\')) > 0 ? user.Name.Substring(domainSep + 1) : user.Name;
        }
    }
}